home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
...taking it to the Macs!
/
...taking it to the Macs!.iso
/
Extras
/
ActiveX Mac SDK
/
ActiveX SDK
/
Container Common
/
memstrm.cpp
< prev
next >
Wrap
Text File
|
1997-01-03
|
7KB
|
301 lines
//
// MEMSTRM.CPP
//
// Copyright (C) Microsoft Corporation, 1996
//
// Implementation of a Netscape stream notification object that "writes" data
// to a memory buffer. This memory buffer can be utilized externally with the
// IStream interface.
//
// This has been broken up into CMemoryStreamNotify which does the simple
// copy-into-memory-buffer logic. CMemoryOleStreamNotify implements an IStream
// interface on top of this class.
//
#include "headers.h"
//
// CMemoryStreamNotify::~CMemoryStreamNotify
//
CMemoryStreamNotify::~CMemoryStreamNotify()
{
if (m_pStream != NULL)
CoTaskMemFree(m_pStream);
}
//
// CMemoryStreamNotify::OnWrite
//
int32
CMemoryStreamNotify::OnWrite(NPStream *stream, int32 offset, int32 len, void
*buffer)
{
#pragma unused (stream, offset)
LPVOID pNewStream;
int32 BytesWritten;
if (m_pStream == NULL) {
pNewStream = (LPVOID) CoTaskMemAlloc(len);
} else {
pNewStream = (LPVOID) CoTaskMemRealloc(m_pStream, m_StreamLength + len);
}
if (pNewStream != NULL) {
BlockMove(buffer, ((LPBYTE) pNewStream + m_StreamLength), len);
m_pStream = pNewStream;
m_StreamLength += len;
BytesWritten = len;
} else {
// Returning a negative value causes the stream to error out and be
// destroyed.
BytesWritten = -1;
}
return BytesWritten;
}
//
// CMemoryOleStreamNotify::IUnknown::QueryInterface
//
STDMETHODIMP
CMemoryOleStreamNotify::QueryInterface(REFIID riid, LPVOID *ppvObj)
{
HRESULT hr;
LPVOID pv;
if (riid == IID_IUnknown || riid == IID_IStream) {
pv = (LPVOID)(LPSTREAM) this;
++m_cRef;
hr = ResultFromScode(S_OK);
} else {
pv = NULL;
hr = ResultFromScode(E_NOINTERFACE);
}
*ppvObj = pv;
return hr;
}
//
// CMemoryOleStreamNotify::IUnknown::AddRef
//
STDMETHODIMP_(ULONG)
CMemoryOleStreamNotify::AddRef(void)
{
return ++m_cRef;
}
//
// CMemoryOleStreamNotify::IUnknown::Release
//
STDMETHODIMP_(ULONG)
CMemoryOleStreamNotify::Release(void)
{
if (--m_cRef != 0)
return m_cRef;
delete this;
return 0;
}
//
// CMemoryOleStreamNotify::IStream::Read
//
STDMETHODIMP
CMemoryOleStreamNotify::Read(void *pv, DWORD cb, LPDWORD pcbRead)
{
// Verify that we're not try to read more bytes than are available. If we
// are, clip the actual number of bytes copied. The OLE32 memory stream
// implementation doesn't return an error, so we won't either.
if (((LONG) cb < 0) || (cb + (ULONG) m_SeekPosition > (ULONG) m_StreamLength)) {
if (m_fAsyncStreamInProgress) {
// Special case: if we're in the middle of streaming some data from
// the network, return E_PENDING so that async binding works
// correctly.
// BUGBUG: Above if statement probably isn't adequate, review this.
return ResultFromScode(E_PENDING);
} else {
cb = m_StreamLength - m_SeekPosition;
}
}
if (cb > 0) {
BlockMove((LPBYTE) m_pStream + m_SeekPosition, pv, cb);
m_SeekPosition += cb;
}
if (pcbRead != NULL)
*pcbRead = cb;
return ResultFromScode(S_OK);
}
//
// CMemoryOleStreamNotify::IStream::Write
//
STDMETHODIMP
CMemoryOleStreamNotify::Write(void const *pv, DWORD cb, LPDWORD pcbWritten)
{
#pragma unused (pv, cb, pcbWritten)
return ResultFromScode(STG_E_ACCESSDENIED);
}
//
// CMemoryOleStreamNotify::IStream::Seek
//
STDMETHODIMP
CMemoryOleStreamNotify::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin,
ULARGE_INTEGER *plibNewPosition)
{
HRESULT hr = ResultFromScode(S_OK);
LONG lMove = (LONG) dlibMove.LowPart;
// Note that we don't care about dlibMove.HighPart. Checking the Win32
// OLE sources, there implementation of a memory stream doesn't bother, so
// if the reference implementation blows off the issue of 64-bit, then we
// sure as hell can. In fact, the below was lifted from OLE.
switch (dwOrigin) {
case STREAM_SEEK_SET:
if (lMove >= 0) {
m_SeekPosition = lMove;
} else {
hr = ResultFromScode(STG_E_SEEKERROR);
}
break;
case STREAM_SEEK_CUR:
if (!(lMove < 0 && ((ULONG) -lMove) > (ULONG) m_SeekPosition)) {
m_SeekPosition += lMove;
} else {
hr = ResultFromScode(STG_E_SEEKERROR);
}
break;
case STREAM_SEEK_END:
if (!(lMove < 0 && ((ULONG) -lMove) > (ULONG) m_StreamLength)) {
m_SeekPosition += m_StreamLength + lMove;
} else {
hr = ResultFromScode(STG_E_SEEKERROR);
}
break;
default:
hr = ResultFromScode(STG_E_INVALIDFUNCTION);
break;
}
if (plibNewPosition != NULL) {
plibNewPosition->HighPart = 0;
plibNewPosition->LowPart = m_SeekPosition;
}
return hr;
}
//
// CMemoryOleStreamNotify::IStream::SetSize
//
STDMETHODIMP
CMemoryOleStreamNotify::SetSize(ULARGE_INTEGER libNewSize)
{
#pragma unused (libNewSize)
// We're a read-only stream, so there's no reason to resize our stream.
return ResultFromScode(STG_E_INVALIDFUNCTION);
}
//
// CMemoryOleStreamNotify::IStream::CopyTo
//
STDMETHODIMP
CMemoryOleStreamNotify::CopyTo(LPSTREAM pstm, ULARGE_INTEGER cb, ULARGE_INTEGER
*pcbRead, ULARGE_INTEGER *pcbWritten)
{
#pragma unused (pstm, cb, pcbRead, pcbWritten)
// There's no good reason for this not to be implemented.
return ResultFromScode(E_NOTIMPL);
}
//
// CMemoryOleStreamNotify::IStream::Commit
//
STDMETHODIMP
CMemoryOleStreamNotify::Commit(DWORD grfCommitFlags)
{
#pragma unused (grfCommitFlags)
// We can always "commit" because it's not possible to write to the stream.
return ResultFromScode(S_OK);
}
//
// CMemoryOleStreamNotify::IStream::Revert
//
STDMETHODIMP
CMemoryOleStreamNotify::Revert(void)
{
// We can always "revert" because it's not possible to write to the stream.
return ResultFromScode(S_OK);
}
//
// CMemoryOleStreamNotify::IStream::LockRegion
//
STDMETHODIMP
CMemoryOleStreamNotify::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
DWORD dwLockType)
{
#pragma unused (libOffset, cb, dwLockType)
return ResultFromScode(STG_E_INVALIDFUNCTION);
}
//
// CMemoryOleStreamNotify::IStream::UnlockRegion
//
STDMETHODIMP
CMemoryOleStreamNotify::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER
cb, DWORD dwLockType)
{
#pragma unused (libOffset, cb, dwLockType)
return ResultFromScode(STG_E_INVALIDFUNCTION);
}
//
// CMemoryOleStreamNotify::IStream::Stat
//
STDMETHODIMP
CMemoryOleStreamNotify::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
{
#pragma unused (grfStatFlag)
// Implementation lifted from OLE32's memory stream.
memset(pstatstg, 0, sizeof(*pstatstg));
pstatstg->type = STGTY_STREAM;
pstatstg->cbSize.LowPart = m_StreamLength;
return ResultFromScode(S_OK);
}
//
// CMemoryOleStreamNotify::IStream::Clone
//
STDMETHODIMP
CMemoryOleStreamNotify::Clone(LPSTREAM *ppstm)
{
*ppstm = NULL;
return ResultFromScode(E_NOTIMPL);
}